﻿using RabbitMQ.Client;
using System;
namespace RabbitMQ.Gateway
{
	public class Publisher : IPublisher
	{
        private static readonly log4net.ILog log = RabbitMQ.Gateway.Log.loger;

        protected IConnection _connection;
		private ConvertToMessage _converter;
		protected IModel _channel;
        private string _routekey;

		public string Exchange
		{
			get;
			internal set;
		}
		public bool Mandatory
		{
			get;
			internal set;
		}
		public bool Immediate
		{
			get;
			internal set;
		}

        public object Clone()
        {
            return this.MemberwiseClone();
        }

        public Publisher(IConnection connection, ConvertToMessage converter, string exchange, string routekey)
        {
            if (connection == null)
            {
                throw new System.ApplicationException("The connection parameter is missing.  A connection is required to publish messages");
            }
            if (converter == null)
            {
                throw new System.ApplicationException("The converter is missing and is required to convert the object to a message for publishing");
            }
            if (string.IsNullOrWhiteSpace(exchange))
            {
                throw new System.ApplicationException("The exchange parameter is missing.  An exchange is required to receive the messages we publish");
            }
            this.Exchange = exchange;
            this._connection = connection;
            this._converter = converter;
            if (this._connection.IsOpen)
            {
                this._channel = this._connection.CreateModel();
            }
            this._routekey = routekey;
        }

        public Publisher(IConnection connection, ConvertToMessage converter, string exchange)
		{
			if (connection == null)
			{
				throw new System.ApplicationException("The connection parameter is missing.  A connection is required to publish messages");
			}
			if (converter == null)
			{
				throw new System.ApplicationException("The converter is missing and is required to convert the object to a message for publishing");
			}
			if (string.IsNullOrWhiteSpace(exchange))
			{
				throw new System.ApplicationException("The exchange parameter is missing.  An exchange is required to receive the messages we publish");
			}
			this.Exchange = exchange;
			this._connection = connection;
			this._converter = converter;
            if (this._connection.IsOpen)
            {
                this._channel = this._connection.CreateModel();
            }
        }

        public bool ChannelIsOpen
        {
            get{ return this._connection.IsOpen &&this._channel!=null && this._channel.IsOpen; }
        }

  
        /// <summary>
        /// send message to mq
        /// </summary>
        /// <param name="ObjectToPublish"></param>
		public bool Publish(object ObjectToPublish)
		{
            if (!this._channel.IsOpen) {
                return false;
            }
            Message message = null;
            try
            {
                if (ObjectToPublish == null)
                {
                    throw new System.ApplicationException("The ObjectToPublish is missing and is required to publish content to the Message bus");
                }
                message = this._converter(this._channel, ObjectToPublish);
                message.Properties.DeliveryMode = 2;
                if (string.IsNullOrWhiteSpace(message.RoutingKey))
                {
                    message.RoutingKey = this._routekey;
                }
                this._channel.BasicPublish(this.Exchange,message.RoutingKey, message.Properties, message.Body);//message.RoutingKey
                return true;
            }
            catch (Exception ex)
            {
                log.ErrorFormat("......消息推送失败：Exchange={0},RoutingKey={1},消息={2},所属节点={3}", this.Exchange, message.RoutingKey, ObjectToPublish,this._connection);
                log.ErrorFormat("......详细错误信息参见:{0}",ex);
                return false;
            }
		}


        /// <summary>
        /// send message to mq
        /// </summary>
        /// <param name="ObjectToPublish"></param>
        /// <param name="RouteKey"></param>
        public bool Publish(object ObjectToPublish,string RouteKey)
        {
            if (!this._channel.IsOpen)
            {
                return false;
            }
            Message message = null;
            try
            {
                if (ObjectToPublish == null)
                {
                    throw new System.ApplicationException("The ObjectToPublish is missing and is required to publish content to the Message bus");
                }
                message = this._converter(this._channel, ObjectToPublish);
                message.Properties.DeliveryMode = 2;
                if (!string.IsNullOrWhiteSpace(RouteKey))
                {
                    message.RoutingKey = RouteKey;
                }
                if (string.IsNullOrWhiteSpace(message.RoutingKey))
                {
                    message.RoutingKey = this._routekey;
                }
                this._channel.BasicPublish(this.Exchange, message.RoutingKey, message.Properties, message.Body);//message.RoutingKey
                return true;
            }
            catch (Exception ex)
            {
                log.ErrorFormat("......消息推送失败：Exchange={0},RoutingKey={1},消息={2},所属节点={3}", this.Exchange, message.RoutingKey, ObjectToPublish, this._connection);
                log.ErrorFormat("......详细错误信息参见:{0}", ex);
                return false;
            }
        }
    }
}
